「RubyでつくるRuby」の interp.rb
Rubyで学ぶRuby 第9回 インタプリタの完成、そしてブートストラップへ
code:interp.rb
require "minruby"
def evaluate(tree, genv, lenv)
when "lit"
when "+"
evaluate(tree1, genv, lenv) + evaluate(tree2, genv, lenv) when "-"
evaluate(tree1, genv, lenv) - evaluate(tree2, genv, lenv) when "*"
evaluate(tree1, genv, lenv) * evaluate(tree2, genv, lenv) when "/"
evaluate(tree1, genv, lenv) / evaluate(tree2, genv, lenv) when "%"
evaluate(tree1, genv, lenv) % evaluate(tree2, genv, lenv) when "<"
evaluate(tree1, genv, lenv) < evaluate(tree2, genv, lenv) when "<="
evaluate(tree1, genv, lenv) <= evaluate(tree2, genv, lenv) when "=="
evaluate(tree1, genv, lenv) == evaluate(tree2, genv, lenv) when "!="
evaluate(tree1, genv, lenv) != evaluate(tree2, genv, lenv) when ">="
evaluate(tree1, genv, lenv) >= evaluate(tree2, genv, lenv) when ">"
evaluate(tree1, genv, lenv) > evaluate(tree2, genv, lenv) when "stmts"
i = 1
last = nil
last = evaluate(treei, genv, lenv) i = i + 1
end
last
when "var_assign"
lenv[tree1] = evaluate(tree2, genv, lenv) when "var_ref"
when "if"
if evaluate(tree1, genv, lenv) evaluate(tree2, genv, lenv) else
evaluate(tree3, genv, lenv) end
when "while"
while evaluate(tree1, genv, lenv) evaluate(tree2, genv, lenv) end
when "func_def"
genv[tree1] = ["user_defined", tree2, tree3] when "func_call"
args = []
i = 0
argsi = evaluate(treei + 2, genv, lenv) i = i + 1
end
else
new_lenv = {}
i = 0
new_lenv[paramsi] = argsi i = i + 1
end
evaluate(mhd2, genv, new_lenv) end
when "ary_new"
ary = []
i = 0
aryi = evaluate(treei + 1, genv, lenv) i = i + 1
end
ary
when "ary_ref"
ary = evaluate(tree1, genv, lenv) idx = evaluate(tree2, genv, lenv) when "ary_assign"
ary = evaluate(tree1, genv, lenv) idx = evaluate(tree2, genv, lenv) val = evaluate(tree3, genv, lenv) when "hash_new"
hsh = {}
i = 0
key = evaluate(treei + 1, genv, lenv) val = evaluate(treei + 2, genv, lenv) i = i + 2
end
hsh
end
end
# ① プログラムの文字列を読み込む
str = minruby_load()
# ② プログラムの文字列を抽象構文木に変換する
tree = minruby_parse(str)
# ③ 抽象構文木を実行(計算)する
genv = {
}
lenv = {}
evaluate(tree, genv, lenv)